﻿namespace NSynx.FlowEngine
{
    using System;
    using System.Collections.Generic;
    using NSynx.FlowEngine.Interfaces;

    public class Flow : IActionContainer , IAction
    {
        private Queue<IAction> actions;
        private IFlowContext flowContext;

        public Flow() : this( null )
        {

        }

        public Flow( IFlowContext context )
        {
            actions = new Queue<IAction>();
            this.flowContext = context;
        }

        #region IActionContainer Members

        /// <summary>
        /// 
        /// </summary>
        /// <param name="action"></param>
        public void Add(IAction action)
        {
            AddItemToTheQueue(action);  
        }

        internal void AddItemToTheQueue(IAction action)
        {
            actions.Enqueue(action);
        }

        

        #endregion

        public int Count
        {
            get
            {
                return actions.Count;
            }
        }

        public void RemoveAll()
        {
            actions.Clear();
        }

        private void Run()
        {
            try
            {
                ProceedToNextStep();
            }
            catch { }
            
        }

        private void ProceedToNextStep()
        {
            if (actions.Count <= 0)
            {
                NoActionLeftToExecute();
                return;
            }

            IAction act = actions.Dequeue();
            
            act.Finished += ProceedToNextStep;

            act.Execute();

            
        }

        private void NoActionLeftToExecute()
        {

        }

        #region IAction Members

        public NSynx.FlowEngine.Enums.Status Whatsup
        {
            get { throw new NotImplementedException(); }
        }

        public string ActionName
        {
            get
            {
                return String.Empty;
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public void Execute()
        {
            this.Run();
        }

        public IList<IParam> InputParameters
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public IList<IParam> OutputParameters
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public void Execute(ISource source)
        {
            this.Run();
        }

        public void Execute(ISource source, IList<IParam> parameters)
        {
            this.Run();
        }

        public event ExecutionEnd Finished;

        #endregion
    }
}
